package com.dingreading.cloud.admin.service.impl;

import com.dingreading.cloud.admin.dto.BookLabelDto;
import com.dingreading.cloud.admin.dto.BooksDto;
import com.dingreading.cloud.admin.dto.vo.BookLabelVO;
import com.dingreading.cloud.admin.entity.Books;
import com.dingreading.cloud.admin.entity.table.BooksTableDef;
import com.dingreading.cloud.admin.mapper.BooksMapper;
import com.dingreading.cloud.admin.service.BooksService;
import com.dingreading.cloud.common.util.PageUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.BatchArgsSetter;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.update.UpdateWrapper;
import com.mybatisflex.core.util.UpdateEntity;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

import static com.mybatisflex.core.query.QueryMethods.max;

/**
 * 服务层实现。
 *
 * @author Administrator
 * @since 2023-11-22
 */
@Service
public class BooksServiceImpl extends BaseServiceImpl<BooksMapper, Books, BooksTableDef> implements BooksService {

    @Override
    protected BooksTableDef getTable() {
        return BooksTableDef.books;
    }

    @Resource
    private BooksMapper booksMapper;


    /**
     * 获取书号最大的
     *
     * @return Books
     */
    @Override
    public Books getMaxBookNum() {
        QueryWrapper wrapper = QueryWrapper.create()
                .select(max(table.id))
                .from(table);

        return getMapper().selectOneByCondition(table.id.eq(wrapper));
    }

    /**
     * 根据书刊id获取
     *
     * @param journalId 书刊id
     * @return list
     */
    @Override
    public List<Books> getByJournalIdOrderByAddTimeAsc(Long journalId) {
        QueryWrapper wrapper = QueryWrapper.create()
                .where(table.journalId.eq(journalId))
                .orderBy(table.addTime.asc());

        return getMapper().selectListByQuery(wrapper);

    }

    /**
     * 根据关键词搜索
     *
     * @return list
     */
    @Override
    public List<Books> searchByKeyword(String keyword) {
        QueryCondition condition = table.isbn.like(keyword).or(table.bookName.like(keyword)).or(table.bookNum.like(keyword));
        condition.and(table.status.eq(1));
        return getMapper().selectListByCondition(condition);
    }

    /**
     * 根据上下架状态搜索
     *
     * @return list
     */
    @Override
    public List<Books> getByStatus(Integer status) {
        return getMapper().selectListByCondition(table.status.eq(status));
    }

    @Override
    public List<Books> getByIsbnAndImgNotNull(List<String> isbns) {
        List<Books> list = booksMapper.getByIsbnAndImgNotNull(isbns);
        return list;
    }

    @Override
    public List<Books> getByIsbnAndLabelNotNull(List<String> isbns) {
        QueryWrapper wrapper = QueryWrapper.create()
                .select(max(table.id))
                .from(table)
                .where(table.isbn.in(isbns).and(table.bookLabelId.isNotNull()))
                .groupBy(table.isbn);

        return getMapper().selectListByCondition(table.id.in(wrapper));
    }

    @Override
    public Page<Books> getNotImg(PageUtil pageUtil) {
        QueryWrapper wrapper = QueryWrapper.create()
                .select()
                .from(table)
                .where(table.img.isNotNull())
                .orderBy(table.id.asc());

        return getMapper().paginate(Page.of(pageUtil.getPage(), pageUtil.getRows()), wrapper);
    }

    @Override
    public int updateImg(List<Long> ids, String img, Date time) {
        Books data = UpdateEntity.of(Books.class);

        UpdateWrapper<Books> wrapper = UpdateWrapper.of(data);
        wrapper.set(table.img, img);

        return getMapper().updateByCondition(data, table.id.in(ids));
    }

    @Override
    public Page<Books> pageList(PageUtil pageUtil, String keyword, Integer status) {

        QueryCondition condition = QueryCondition.createEmpty();
        if (null != status)
            condition.and(table.status.eq(status));
        if (StringUtils.isNotBlank(keyword))
            condition.and(table.bookName.like(keyword)
                    .or(table.isbn.like(keyword))
                    .or(table.bookNum.like(keyword))
                    .or(table.author.like(keyword))
                    .or(table.press.like(keyword)));

        QueryWrapper wrapper = QueryWrapper.create()
                .select(table.id, table.bookName, table.isbn, table.bookNum, table.author, table.bookLabelId,
                        table.bookLabelName, table.unitPrice, table.press, table.wordCount, table.source, table.status,
                        table.editTime)
                .from(table)
                .where(table.img.isNotNull())
                .orderBy(table.id.asc());

        return getMapper().paginate(Page.of(pageUtil.getPage(), pageUtil.getRows()), wrapper);
    }

    @Override
    public List<BooksDto> getByIsbns(List<String> isbns) {
        QueryWrapper wrapper2 = QueryWrapper.create()
                .select(table.id)
                .from(table)
                .where(table.isbn.in(isbns));

        QueryWrapper wrapper = QueryWrapper.create()
                .select(table.isbn, table.bookName)
                .from(table)
                .where(table.isbn.in(isbns).and(table.id.in(wrapper2)));

        return getMapper().selectListByQueryAs(wrapper, BooksDto.class);
    }

    @Override
    public int dropBean(Long id) {
        return getMapper().deleteById(id);
    }

    @Override
    public int updateStatus(Long id, Integer status) {
        Books data = UpdateEntity.of(Books.class);

        UpdateWrapper<Books> wrapper = UpdateWrapper.of(data);
        wrapper.set(table.status, status);

        return getMapper().updateByCondition(data, table.id.eq(id));
    }

    @Override
    public void saveBatch(List<Books> list) {
        //批量转数组
        Db.executeBatch(list.size(), 500, BooksMapper.class, (mapper, index) -> {
            Books books = list.get(index);
            getMapper().insert(books);
        });
    }

    @Override
    public List<BookLabelDto> labelListByIsbnIn(List<String> isbnList) {
        QueryCondition condition = table.isbn.in(isbnList)
                .and(table.bookLabelId.isNotNull())
                .and(table.bookLabelName.isNotNull());
        QueryWrapper wrapper = QueryWrapper.create()
                .select(table.isbn, table.bookLabelId, table.bookLabelName)
                .from(table)
                .where(condition);
        return getMapper().selectListByQueryAs(wrapper, BookLabelDto.class);
    }

    @Override
    public void dbUpdateLabelInfoByIsbn(List<BookLabelVO> voList) {
        String sql = "update books set book_label_id=?, book_label_name=? where isbn=?";
        Db.updateBatch(sql, new BatchArgsSetter() {
            @Override
            public int getBatchSize() {
                return voList.size();
            }

            @Override
            public Object[] getSqlArgs(int index) {
                BookLabelVO vo = voList.get(index);
                Object[] args = new Object[3];
                args[0] = vo.getLabelId();
                args[1] = vo.getLabelName();
                args[2] = vo.getIsbn();
                return args;
            }
        });
    }

}
